<script lang="ts" setup>
import { ref, onMounted, computed, nextTick } from 'vue'
import transferCheckbox from './components/transfer-checkbox.vue'
import suffixItem from './components/suffix-item.vue'
import formTable from './components/form-table.vue'
import doubleInputNumber from './components/double-input-number.vue'
import Fldm from '@/utils/fldm'
import axios from '@/request/http'
import { ElMessage } from 'element-plus'
import { encrypt } from '@/utils/aes'
const props = defineProps({
  formItem: Object,
  modelValue: [Array, String, Boolean, Number],
  form: Object,
  zdlxArr: Array<any>,
  isReadonly: Boolean,
})
const emit = defineEmits([
  'updateModelValue',
  'exportCallBack',
  'update:modelValue',
  'changeCallBack',
])
// 生命周期
onMounted(() => {
  // 获取数据源
  getOption()
  if (props.formItem?.multiple) {
    modelValue.value = props.form?.[props.formItem?.value] || []
  } else {
    if (props.formItem?.tag === 'inputnumber') {
      modelValue.value = props.form?.[props.formItem?.value]
        ? Number(props.form?.[props.formItem?.value])
        : null
    } else {
      modelValue.value = props.form?.[props.formItem?.value] || null
    }
  }
  comInputPlaceholder()
})
const modelValue: any = computed({
  get() {
    return props.modelValue
  },
  set(val: any) {
    // 判断一下是否是穿梭框
    emit('update:modelValue', val)
  },
})
/* 初始化 */
const clearData = () => {
  if (props.formItem?.multiple) {
    modelValue.value = []
  } else {
    if (props.formItem?.tag === 'inputnumber') {
      modelValue.value = null
    } else {
      modelValue.value = ''
    }
  }
}
/* 获取数据源 */
const options = ref<Array<any>>([])
const loading = ref<boolean>(false)
const getOption = async (isBtn = false) => {
  if (props.formItem?.url) {
    // 这里还要判断一下接口入参是否必填
    const bol = props.formItem?.methodsParams?.every((cur: any): boolean => {
      return !cur.required || (cur.required && props.form?.[cur.name])
    })
    if (!bol && props.formItem?.methodsParams?.length) {
      if (isBtn) {
        loading.value = false
      }
      return
    }
    // 组装请求参数
    let params: any = {}
    props.formItem?.methodsParams?.map((cur: any) => {
      params[cur.name] = props.form?.[cur.name] || cur.defaultValue
    })
    if (['querySjymsm'].includes(props.formItem?.url)) {
      // 加密密码
      params.mm = params.mm ? encrypt(params.mm) : ''
      params.lxmc = params.lxmc.replace('归档', '')
    }
    let res: any = []
    try {
      if (props.formItem?.apiServeName) {
        // 这里可能url是可以完整的地址，所以如果没传递apiServeName，不通过模块访问，通过axios访问
        const module = await import(`../../api/${props.formItem?.apiServeName}.ts`)
        res = await module.default[props.formItem?.url](params).catch((err: any) => {
          !err.isError && ElMessage({ type: 'warning', message: err.message })
        })
      } else {
        res = await axios.post(props.formItem?.url, params).catch((err) => {
          !err.isError && ElMessage({ type: 'warning', message: err.message })
        })
      }
      if (isBtn) {
        loading.value = false
      }
      if (!res.data) {
        options.value = []
        return
      }
      let option = res?.data || []
      // 这里需要对某些特殊的接口做处理
      if (['querySjymsm'].includes(props.formItem?.url) && props.formItem.tag === 'select') {
        // 返回为字符串数组的下拉选项的
        options.value = option.map(
          (
            cur: string,
          ): {
            dm: string
            mc: string
          } => {
            return {
              dm: cur,
              mc: cur,
            }
          },
        )
      } else if (props.formItem?.defaultProps) {
        // 配置了key，value的，单独对sheet做单独处理
        let arr: any = []
        if (props.formItem?.value === 'sheet') {
          arr = option?.bxxes
        } else {
          arr = option
        }
        options.value = arr.map((cur: any) => {
          return {
            ...cur,
            dm: cur[props.formItem?.defaultProps.nodeKey],
            mc: cur[props.formItem?.defaultProps.label],
          }
        })
        // 如果配置了replaceModelValue， 直接将数据源替换到绑定的modelValue
        if (props.formItem?.replaceModelValue) {
          modelValue.value = option
        }
      } else {
        options.value = option
      }
    } catch {
      if (isBtn) {
        loading.value = false
      }
    }
  } else if (props.formItem?.lbbm) {
    options.value = await Fldm.getFldmlb(props.formItem?.lbbm)
  } else if (props.formItem?.initData && props.formItem?.value === 'zlzd') {
    options.value = (props.form?.zdlb || []).map((cur: string) => {
      return {
        dm: cur,
        mc: cur,
      }
    })
  }
}
/* 设置数据源 */
const setOption = (arr: any, label: string, value: string) => {
  if (props.formItem?.value === 'zlzd') {
    options.value = arr.map((cur: any) => {
      return {
        dm: cur,
        mc: cur,
      }
    })
  }
}
const selectRef = ref()
// 下拉、单选框改变
const changValue = (val: string) => {
  const temp = options.value.find((el: any) => {
    return el.dm === val
  })
  if (props.formItem?.changeCallBack) {
    // 改变回调
    emit('changeCallBack', props.formItem, 'changeCallBack')
  }
  if (!props.formItem?.labelValue) {
    return
  }
  emit('updateModelValue', temp?.mc, 'labelValue', props.formItem)
}
/* 多选框改变 */
const changeCheckbox = (val: string[] | undefined) => {
  if (!props.formItem?.labelValue) {
    return
  }
  let mc = ''
  if (val?.length) {
    const arr = []
    for (const el of val) {
      for (const item of options.value) {
        if (el === item.dm) {
          arr.push(item)
        }
      }
    }
    mc = arr.map((el) => el.mc).join(',')
  }
  emit('updateModelValue', mc, 'labelValue', props.formItem)
}
/* 下拉树选中 */
const nodeClick = (data: any) => {
  if (!props.formItem?.labelValue) {
    return
  }
  emit('updateModelValue', data[props.formItem?.defaultProps.label], 'labelValue', props.formItem)
}
const treeRef = ref()
/* 树多选回调 */
const treeCheckChange = () => {
  if (!props.formItem?.labelValue) {
    return
  }
  const nodes = treeRef.value.getCheckedNodes()
  const mcArr = nodes.map((cur: any) => {
    return cur[props.formItem?.defaultProps.label]
  })
  emit('updateModelValue', mcArr, 'labelValue', props.formItem)
}
/* 按钮回调 */
const exportCallBack = (type: string, funName: string) => {
  if (props.formItem?.url) {
    loading.value = true
    getOption(true)
  }
  emit('exportCallBack', type, funName, props.formItem)
}
/* 添加表格行 */
const tableRef = ref()
const addCol = () => {
  nextTick(() => {
    tableRef.value.addCol()
  })
}
// 穿梭框选中回调
const checkboxChange = () => {
  if (props.formItem?.changeCallBack) {
    emit('changeCallBack', props.formItem, 'changeCallBack')
  }
}
/* 渲染输入框placeholder */
const comInputPlaceholder = () => {
  if (props.formItem?.value === 'url' && props.form?.lxdm.startsWith('40708410074455450')) {
    const lbbmList = Fldm.getFldmlb('1101')
    const sm = lbbmList.find((item: any) => {
      return item.dm === props.form?.lxdm
    })?.sm
    if (!modelValue.value) {
      modelValue.value = sm
    }
  }
}
// 获取选中option
const getNodeOption = () => {
  if (props.formItem?.tag === 'select') {
    // 下拉
    if (props.formItem?.multiple) {
      // 多选
      return options.value.filter((item: any) => {
        return modelValue.value.includes(item[props.formItem?.defaultProps.nodeKey])
      })
    } else {
      // 单选
      return options.value.find((item: any) => {
        return modelValue.value === item[props.formItem?.defaultProps.nodeKey]
      })
    }
  } else if (props.formItem?.tag === 'selecttree') {
    // 下拉树
    if (props.formItem?.multiple) {
      // 多选
      const nodes = treeRef.value.getCheckedNodes()
      return nodes
    } else {
      // 多选
      const node = treeRef.value.getCurrentNode()
      return node
    }
  } else {
    return null
  }
}
defineExpose({ clearData, getOption, setOption, addCol, getNodeOption })
</script>
<template>
  <div class="form-item">
    <!-- 前面组件 -->
    <suffix-item
      :disabled="props.formItem.disabled || isReadonly"
      v-if="props.formItem?.prevType"
      @exportCallBack="exportCallBack"
      :formItem="props.formItem"
      type="prev"
    ></suffix-item>
    <!-- 输入框 -->
    <el-input
      v-if="props.formItem?.tag === 'input'"
      v-model="modelValue"
      class="form-item-content"
      :placeholder="props.formItem?.placeholder || ''"
      :disabled="props.formItem.disabled || isReadonly"
      :maxlength="props.formItem.maxLength"
      @keyup.stop
      clearable
    />
    <!-- 数字输入框 -->
    <el-input-number
      v-if="props.formItem?.tag === 'inputnumber'"
      v-model="modelValue"
      class="form-item-content"
      :style="{ width: props.formItem.tagParams.width || '50%' }"
      v-bind="props.formItem.tagParams"
      :step="props.formItem.step"
      :placeholder="props.formItem.placeholder || ''"
      :disabled="props.formItem.disabled || isReadonly"
      @keyup.stop
    >
    </el-input-number>
    <!-- 密码输入框 -->
    <el-input
      v-if="props.formItem?.tag === 'inputPassword'"
      type="password"
      class="form-item-content"
      v-model="modelValue"
      show-password
      :placeholder="props.formItem.placeholder || ''"
      :disabled="props.formItem.disabled || isReadonly"
      :maxlength="props.formItem.maxLength"
      @keyup.stop
      clearable
    >
    </el-input>
    <!-- 下拉框 -->
    <el-select
      v-if="props.formItem?.tag === 'select'"
      v-model="modelValue"
      ref="selectRef"
      :allow-create="props.formItem?.allowCreate"
      class="form-item-content"
      filterable
      :multiple="props.formItem.multiple"
      :collapse-tags="props.formItem.collapseTags"
      :disabled="props.formItem.disabled || isReadonly"
      :placeholder="props.formItem.placeholder || ''"
      :popper-append-to-body="false"
      @change="changValue"
      clearable
    >
      <el-option v-for="item in options" :key="item.dm" :label="item.mc" :value="item.dm">
      </el-option>
    </el-select>
    <!-- 日期 -->
    <el-date-picker
      class="form-item-content"
      v-if="props.formItem?.tag === 'date'"
      v-model="modelValue"
      :disabled="props.formItem.disabled || isReadonly"
      type="date"
      clearable
      format="YYYY-MM-DD"
      value-format="YYYY-MM-DD"
      :placeholder="props.formItem.placeholder || ''"
      style="width: 100%"
    >
    </el-date-picker>
    <!-- 多行文本 -->
    <el-input
      v-if="props.formItem?.tag === 'textarea'"
      class="form-item-content"
      v-model="modelValue"
      :disabled="props.formItem.disabled || isReadonly"
      resize="none"
      type="textarea"
      :rows="props.formItem.rows"
      show-word-limit
      :maxlength="props.formItem.maxLength"
      :placeholder="props.formItem.placeholder || ''"
      clearable
    >
    </el-input>
    <!-- 下拉树 -->
    <el-tree-select
      v-if="props.formItem?.tag === 'selecttree'"
      class="form-item-content"
      v-model="modelValue"
      :data="options"
      :props="props.formItem.defaultProps"
      style="width: 100%"
      :check-strictly="props.formItem.checkStrictly"
      ref="treeRef"
      :show-checkbox="props.formItem.multiple"
      :multiple="props.formItem.multiple"
      :collapse-tags="props.formItem.collapseTags"
      :disabled="props.formItem.disabled || isReadonly"
      :node-key="props.formItem.nodeKey"
      @node-click="nodeClick"
      @check-change="treeCheckChange"
    ></el-tree-select>
    <!-- 多选 -->
    <el-checkbox-group
      v-if="props.formItem?.tag === 'checkbox'"
      v-model="modelValue"
      class="form-item-content"
      :disabled="props.formItem.disabled || isReadonly"
      style="width: 100%"
      @change="changeCheckbox"
    >
      <el-checkbox v-for="(item, index) in options" :key="index" :label="item.dm">
        {{ item.mc }}
      </el-checkbox>
    </el-checkbox-group>
    <!-- 单选 -->
    <el-radio-group
      v-if="props.formItem?.tag === 'radio'"
      v-model="modelValue"
      :disabled="props.formItem.disabled || isReadonly"
      class="form-item-content"
      @change="changValue"
    >
      <el-radio v-for="item in options" :key="item.dm" :value="item.dm">
        {{ item.mc }}
      </el-radio>
    </el-radio-group>
    <!-- switch单选 -->
    <el-switch
      v-if="props.formItem?.tag === 'switch'"
      v-model="modelValue"
      class="form-item-content"
      v-bind="props.formItem.tagParams"
      :disabled="props.formItem.disabled || isReadonly"
    >
    </el-switch>
    <!-- 穿梭框选中 -->
    <transfer-checkbox
      :disabled="props.formItem.disabled || isReadonly"
      v-if="props.formItem?.tag === 'transfer'"
      @checkboxChange="checkboxChange"
      :style="{ width: props.formItem.width || '100%', height: props.formItem.height }"
      v-model="modelValue"
      :options="options"
      class="form-item-content"
      :formItem="formItem"
    >
    </transfer-checkbox>
    <!-- 表格 -->
    <form-table
      v-if="props.formItem?.tag === 'table'"
      :disabled="props.formItem.disabled || isReadonly"
      class="form-item-content"
      ref="tableRef"
      :zdlxArr="zdlxArr"
      v-model="modelValue"
      :formItem="formItem"
    />
    <!-- 图片 -->
    <img
      v-if="props.formItem?.tag === 'img'"
      src=""
      class="sjylx-item-img form-item-content"
      :style="{ width: props.formItem.imgWidth, height: props.formItem.imgHeight }"
    />
    <!-- 行列输入框 -->
    <double-input-number
      v-if="props.formItem?.tag === 'doubleinputnumber'"
      class="form-item-content"
      v-model="modelValue"
      :formItem="formItem"
      :disabled="props.formItem.disabled || isReadonly"
    />
    <!-- 后面组件 -->
    <suffix-item
      :disabled="props.formItem.disabled || isReadonly"
      v-if="props.formItem?.suffixType"
      :formItem="formItem"
      v-model:loading="loading"
      type="suffix"
      @exportCallBack="exportCallBack"
    ></suffix-item>
  </div>
</template>
<style lang="scss" scoped>
.form-item {
  width: 100%;
  align-items: center;
  display: flex;
  .form-item-content {
    flex: 1;
  }
}
:deep(.ep-input__wrapper) {
  width: 100%;
}
</style>
